package DEEPERsource.DEEPERsource.source.parser.stanfordparser.JUNGadapter;

import java.util.Collection;

import parser.StructuredSentence;


import jung.entities.Graph;

import edu.stanford.nlp.ling.Sentence;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TypedDependency;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.utils.UserData;
import graph.GraphFactory;
import graph.Keys;

/**
 * Factory converts Stanford Parser parse and dependency tree representations
 * to the JUNG graph format.
 * Note, that the only JUNG dependency is return types
 * All other specific code is isolated in separate builders
 * @author tfayruzo
 *
 */
public class StanfordGraphFactory implements GraphFactory<Collection<TypedDependency>, Tree, Sentence<TaggedWord>>{
	
	/**
	 * 
	 * @param depTree - Stanford Parser dependency tree
	 * @return directed graph (with tree skeleton) in JUNG format
	 */
	public Graph getDepGraph(Collection<TypedDependency> depTree){
		DependencyTreeBuilder builder = new DependencyTreeBuilder();
		builder.init();
		for(TypedDependency dep : depTree){
			builder.add(dep);
		}
		Graph depGraph = builder.getDepTree();
		//depGraph.initRoot();
		return depGraph;
	}
	
	/**
	 * 
	 * @param parseTree - Stanford Parser dependency tree
	 * @return directed tree graph in JUNG format
	 */
	public Graph getParseGraph(Tree parseTree){
		internalId = -1;
		ParseTreeBuilder builder = new ParseTreeBuilder();
		builder.init(parseTree);
		buildTree(parseTree, builder);
		return builder.getParseTree();
	}
	
	public StructuredSentence getSentence(Sentence<TaggedWord> sentence) {
		return new StructuredSentence(sentence);
	}
	
	//---------non-interface methods-------
	
	public Graph addPOS(Graph g, StructuredSentence sentence){
		for(Object o : g.getVertices()){
			Vertex v = (Vertex) o;
			v.setUserDatum(Keys.POS, 
					sentence.getTag((Integer)v.getUserDatum(Keys.INDEX)-1), 
					UserData.SHARED);
		}
		return g;		
	}
	
	//---------private methods-------------
	
	private int internalId;
	private void buildTree(edu.stanford.nlp.trees.Tree tree, ParseTreeBuilder builder){
		int parent = builder.getInternalId();
		for(edu.stanford.nlp.trees.Tree child : tree.children()){
			//builder.setParent(parentId);
			if(!child.isLeaf())
				builder.addInnerEdge(parent, child);
			else{
				builder.addLeafEdge(parent, child);
			}
			buildTree(child, builder);			
		}
	}
}
